﻿using System.Data;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using CodeCrawler.UI.Engine.KeyPointersScan.Exceptions;
using OWASP.CodeReview.CodeCrawler.Engine.Exceptions;
using OWASP.CodeReview.CodeCrawler.Engine.Interfaces;
using OWASP.CodeReview.CodeCrawler.Enums;

namespace CodeCrawler.UI.Data {

    internal class CodeCrawlerXMLDatabase : IDatabaseObject {
        #region IDatabaseObject Members
        public DataSet ThreatList { get; set; }


        /// <summary>
        /// Create and Return an instance of CodeCrawlerDatabase
        /// </summary>
        /// <returns></returns>
        public DataSet InizializeCodeCrawlerDatabase() {

            var xmlDatabasePath = new StringBuilder();
            xmlDatabasePath.Append(Application.StartupPath);
            xmlDatabasePath.Append("/DataBase");
            xmlDatabasePath.Append("/CodeCrawlerDatabase.xml");

            var databaseObjectFile = new FileInfo(xmlDatabasePath.ToString());

            if (databaseObjectFile.Exists) {
                // Demend IO read permission before proceding
                var fileIoReadPermission = new FileIOPermission(PermissionState.None);
                fileIoReadPermission.AddPathList(FileIOPermissionAccess.Read, xmlDatabasePath.ToString());

                try {
                    fileIoReadPermission.Demand();
                }
                catch (SecurityException) {
                    throw new DatabaseSecurityException();
                }

                var xmlDataSet = new DataSet();

                // XMLException / Invalid chars within the XML File
                try { xmlDataSet.ReadXml(databaseObjectFile.FullName); }
                catch (XmlException) {
                    MessageBox.Show("Invalid database content, this may occur because of invalid XML values within the database.", "Error reading XML File", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                return xmlDataSet;
            }
            throw new UnableToLocateDatabaseException();
        }


        /// NOTE: TEST METHOD REQUIRED IN ORDER TO MAKE RESHARPER WORK WITH MBUNIT TestFixture
        /// <summary>
        /// Create and Return an instance of CodeCrawlerDatabase
        /// </summary>
        /// <returns></returns>
        public DataSet InizializeCodeCrawlerDatabase(string folderPath) {

            var xmlDatabasePath = new StringBuilder();
            xmlDatabasePath.Append(folderPath);
            xmlDatabasePath.Append("/DataBase");
            xmlDatabasePath.Append("/CodeCrawlerDatabase.xml");

            var databaseObjectFile = new FileInfo(xmlDatabasePath.ToString());

            if (databaseObjectFile.Exists) {
                // Demend IO read permission before proceding
                var fileIoReadPermission = new FileIOPermission(PermissionState.None);
                fileIoReadPermission.AddPathList(FileIOPermissionAccess.Read, xmlDatabasePath.ToString());

                try {
                    fileIoReadPermission.Demand();
                }
                catch (SecurityException) {
                    throw new DatabaseSecurityException();
                }

                var xmlDataSet = new DataSet();

                // XMLException / Invalid chars within the XML File
                try { xmlDataSet.ReadXml(databaseObjectFile.FullName); }
                catch (XmlException xe) {
                    MessageBox.Show("Invalid database content, this may occur because of invalid XML values within the database.", "Error reading XML File", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                return xmlDataSet;
            }
            throw new UnableToLocateDatabaseException();
        }


        /// <summary>
        /// Create Threat Table
        /// </summary>
        /// <param name="dataTableToCreate"></param>
        public void CreateThreatTable(DataTable dataTableToCreate) {
            if (dataTableToCreate != null) {

                var column1 = new DataColumn("Threat",      typeof (string));
                var column2 = new DataColumn("Description", typeof (string));
                var column3 = new DataColumn("Level",       typeof (ThreatLevel));
                var column4 = new DataColumn("Line",        typeof (int));
                var column5 = new DataColumn("Owasp",       typeof (string));

                dataTableToCreate.Columns.Add(column1);
                dataTableToCreate.Columns.Add(column2);
                dataTableToCreate.Columns.Add(column3);
                dataTableToCreate.Columns.Add(column4);
                dataTableToCreate.Columns.Add(column5);
            }
        }
        #endregion
    }
}